//	PositionDisplay.java --- 

package fr.upmc.dtgui.example.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

import fr.upmc.dtgui.example.robot.PositioningData;

/**
 * The class <code>PositionDisplay</code> implements a radar-like display for
 * the robot teleoperation GUI.  The robot has an absolute position in the
 * positive x, y quadrant which is repositioned in the referential of the
 * 1000x1000 meters of the display given its central position.  The robot is
 * represented by a dot, and its direction is made visible with a small line.
 * As the robot moves, a trace of its preceding position is left on the screen
 * to see its overall path.
 *
 * <p><strong>Invariant</strong></p>
 * 
 * <pre>
 * invariant	true
 * </pre>
 * 
 * <p>Created on : 2011-09-19</p>
 * 
 * @author	<a href="mailto:Jacques.Malenfant@lip6.fr">Jacques Malenfant</a>
 * @version	$Name$ -- $Revision$ -- $Date$
 */
public class PositionDisplay extends JPanel {

	private static final long		serialVersionUID = 1L;
	protected ArrayList<RobotDisplayModel>		models ;
	protected Color					backgroundColor ;
	protected Color					foregroundColor ;
	protected Color					traceColor ;
	protected int					absoluteX ;
	protected int					absoluteY ;
	protected int					nbRobots ;

	public 				PositionDisplay(
		Color backgroundColor,
		Color foregroundColor,
		Color traceColor,
		int absoluteX,
		int absoluteY,
		int nbRobots
		)
	{
		super();
		this.nbRobots = nbRobots;
		this.backgroundColor = backgroundColor;
		this.foregroundColor = foregroundColor;
		this.traceColor = traceColor;
		this.absoluteX = absoluteX;
		this.absoluteY = absoluteY;
		//this.model = new RobotDisplayModel(0, 0, 0, 0) ;
		this.models = new ArrayList<RobotDisplayModel>();
		for(int i=0; i<nbRobots; i++)
			this.models.add(new RobotDisplayModel(nbRobots*10, nbRobots*10, 0, 0, i));
		this.setSize(1000, 1000) ;
		this.setBackground(this.backgroundColor) ;
		this.setForeground(this.foregroundColor) ;
		this.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2)) ;
	}

	public RobotDisplayModel getModel(int ind) {
		return models.get(ind);
	}

	public void setModel(RobotDisplayModel model, int ind) {
		this.models.set(ind, model);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		this.setSize(1000, 1000) ;
		g.setColor(this.foregroundColor) ;
		g.drawOval(100, 100, 800, 800) ;
	}

	public void			draw(PositioningData pd) {
		for(RobotDisplayModel m : models) {
			Graphics g = this.getGraphics() ;
			g.setColor(this.backgroundColor) ;
		
			m.setVisible(true) ;
			m.draw(g) ;
			g.setColor(this.traceColor) ;
			g.fillOval(m.currentX - 5, m.currentY - 5, 10, 10) ;
			g.setColor(this.foregroundColor) ;
			m.update(
				(((int) Math.round(pd.x)) - this.absoluteX) + 500,
				(((int) Math.round(pd.y)) - this.absoluteY) + 500,
				(int) Math.round(10.0 * Math.cos(Math.toRadians(pd.direction))),
				(int) Math.round(10.0 * Math.sin(Math.toRadians(pd.direction)))) ;
			m.draw(g) ;
			g.drawOval(100, 100, 800, 800) ;
		}
		
	}
	
}

class RobotDisplayModel {
	protected boolean	visible ;
	protected int		currentX ;
	protected int		currentY ;
	protected int		currentDeltaX ;
	protected int		currentDeltaY ;
	protected int		ind ;

	public				RobotDisplayModel(
		int currentX,
		int currentY,
		int currentDeltaX,
		int currentDeltaY,
		int ind
		)
	{
		super();
		this.ind = ind ;
		this.visible = false ;
		this.currentX = currentX;
		this.currentY = currentY;
		this.currentDeltaX = currentDeltaX;
		this.currentDeltaY = currentDeltaY;
	}

	public boolean isVisible() {
		return visible;
	}

	public void setVisible(boolean visible) {
		this.visible = visible;
	}

	public void			update(
		int currentX,
		int currentY,
		int currentDeltaX,
		int currentDeltaY
		)
	{
		this.currentX = currentX;
		this.currentY = currentY;
		this.currentDeltaX = currentDeltaX;
		this.currentDeltaY = currentDeltaY;
	}

	public void			draw(Graphics g) {
		if (this.visible) {
			if (this.inDisplay()) {
				g.fillOval(this.currentX - 5, this.currentY - 5, 10, 10) ;
				g.drawLine(this.currentX, this.currentY,
					this.currentX + this.currentDeltaX,
					this.currentY + this.currentDeltaY) ;
			}
		}
	}

	public boolean		inDisplay() {
		return	this.currentX >= 0 && this.currentX <= 1000 &&
				this.currentY >= 0 && this.currentY <= 1000 ;
		
	}
}

// $Id$